#include <sourcemod>
#include <sdktools>

new	Handle:g_cvJumpBoost	= INVALID_HANDLE;
new	Handle:g_cvJumpEnable	= INVALID_HANDLE;
new	Handle:g_cvJumpMax		= INVALID_HANDLE;

new	Float:g_flBoost = 250.0

new	bool:g_bDoubleJump = true;
new bool:DoubleJumpEnabled[MAXPLAYERS+1] = {true,...};

new	g_fLastButtons[MAXPLAYERS+1];
new	g_fLastFlags[MAXPLAYERS+1];
new	g_iJumps[MAXPLAYERS+1];
new g_iJumpMax;

public Plugin:myinfo =
{
	name		    = "Togglable Double Jump",
	author		= "Paegus - Edited by Marcus",
	description	= "Allows the toggling of double-jumping.",
	version		= "1.1.0",
	url			= ""
}
	
public OnPluginStart()
{
	RegAdminCmd("sm_ddt", Command_Jump, 0, "多段跳指令开关.");

	g_cvJumpEnable = CreateConVar("sm_doublejump_enabled", "1", "开启多段跳.",	FCVAR_NOTIFY);
	g_cvJumpBoost = CreateConVar("sm_doublejump_boost", "450.0",	"跳跃高度.",	FCVAR_NOTIFY);
	g_cvJumpMax = CreateConVar("sm_doublejump_max", "1", "跳跃次数.",	FCVAR_NOTIFY);

	//AutoExecConfig(true, "doublejump");
	
	HookConVarChange(g_cvJumpBoost, convar_ChangeBoost)
	HookConVarChange(g_cvJumpEnable, convar_ChangeEnable)
	HookConVarChange(g_cvJumpMax, convar_ChangeMax)
	
	g_bDoubleJump	= GetConVarBool(g_cvJumpEnable)
	g_flBoost = GetConVarFloat(g_cvJumpBoost)
	g_iJumpMax = GetConVarInt(g_cvJumpMax)
}

public convar_ChangeBoost(Handle:convar, const String:oldVal[], const String:newVal[]) {
	g_flBoost = StringToFloat(newVal)
}

public convar_ChangeEnable(Handle:convar, const String:oldVal[], const String:newVal[]) {
	if (StringToInt(newVal) >= 1) {
		g_bDoubleJump = true
	} else {
		g_bDoubleJump = false
	}
}

public convar_ChangeMax(Handle:convar, const String:oldVal[], const String:newVal[]) {
	g_iJumpMax = StringToInt(newVal)
}

public OnGameFrame()
{
	if (g_bDoubleJump) {
		for (new i = 1; i <= MaxClients; i++) {
			if (IsClientInGame(i) && IsPlayerAlive(i) && DoubleJumpEnabled[i]) {
				DoubleJump(i)
			}
		}
	}
}
stock DoubleJump(const any:client) {
	new
		fCurFlags	= GetEntityFlags(client),
		fCurButtons	= GetClientButtons(client)
	
	if (g_fLastFlags[client] & FL_ONGROUND) {
		if (
			!(fCurFlags & FL_ONGROUND) &&
			!(g_fLastButtons[client] & IN_JUMP) &&
			fCurButtons & IN_JUMP
		) {
			OriginalJump(client)
		}
	} else if (
		fCurFlags & FL_ONGROUND
	) {
		Landed(client)
	}
	else if (!(g_fLastButtons[client] & IN_JUMP) && fCurButtons & IN_JUMP)
	{
		ReJump(client)
	}
	
	g_fLastFlags[client] = fCurFlags
	g_fLastButtons[client] = fCurButtons
}

stock OriginalJump(const any:client)
{
	g_iJumps[client]++
}

stock Landed(const any:client)
{
	g_iJumps[client] = 0
}

stock ReJump(const any:client)
{
	if ( 1 <= g_iJumps[client] <= g_iJumpMax)
	{
		g_iJumps[client]++
		decl Float:vVel[3]
		GetEntPropVector(client, Prop_Data, "m_vecVelocity", vVel)
		
		vVel[2] = g_flBoost
		TeleportEntity(client, NULL_VECTOR, NULL_VECTOR, vVel)
	}
}

public Action Command_Jump(int client, int args)
{
	if (!DoubleJumpEnabled[client])
	{
		for (int i = 1; i <= MaxClients; i++)
		{
			if (IsClientConnected(i) && IsClientInGame(i) && !IsFakeClient(i))
			{
				DoubleJumpEnabled[i] = true;
				PrintToChat(i, "\x04[提示]\x05管理员已\x03开启\x05多段跳.");
			}
		}
		
	}
	else
	{
		for (int i = 1; i <= MaxClients; i++)
		{
			if (IsClientConnected(i) && IsClientInGame(i) && !IsFakeClient(i))
			{
				DoubleJumpEnabled[i] = false;
				PrintToChat(i, "\x04[提示]\x05管理员已\x03关闭\x05多段跳.");
			}
		}
	}
	return Plugin_Handled;
}

